package com.example.zzpneo4j.service;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.alibaba.excel.support.ExcelTypeEnum;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.example.zzpneo4j.TimeUtil;
import com.example.zzpneo4j.config.MinioUtil;
import com.example.zzpneo4j.config.Neo4jUtil;
import com.example.zzpneo4j.dto.Entity;
import com.example.zzpneo4j.dto.ExamMsg;
import com.example.zzpneo4j.dto.GraphImage;
import com.example.zzpneo4j.dto.Result;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.neo4j.driver.v1.Driver;
import org.neo4j.driver.v1.Session;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.IOException;
import java.util.*;
import java.util.function.Consumer;
import java.util.stream.Collectors;

@Service
public class Neo4jService {
    @Resource
    MinioUtil minioUtil;
    @Resource
    Neo4jUtil neo4jUtil;

    static GraphImage graphImage = new GraphImage();

    public void test() {
        Entity entity = new Entity();
        entity.setName("zzp1");
//        neo4jTemplate.save(entity);

//        List<Entity> all = neo4jTemplate.find(Entity.class).all();
//        System.out.println(all);
    }

    public List<Entity> loadCsv(MultipartFile file, String labels) throws IOException {

        minioUtil.uploadFile(file.getInputStream(), file.getOriginalFilename());
        String url = minioUtil.getFileUrl(file.getOriginalFilename());
        ExcelService readListener = new ExcelService();
        readListener.setUrl(url);
        readListener.setFileName(file.getOriginalFilename());
        readListener.setLabels(labels);
        if (Objects.requireNonNull(file.getOriginalFilename()).endsWith(ExcelTypeEnum.CSV.getValue())) {
            EasyExcel.read(file.getInputStream(), readListener)
                    .excelType(ExcelTypeEnum.CSV)
                    .sheet().doRead();
        } else {
            EasyExcel.read(file.getInputStream(), readListener)
                    .sheet().doRead();
        }
        return null;
    }

    public void loadCsv(String lineName, String filePath, String fileName, String labels) {

        int lastIndex = fileName.lastIndexOf(".");
        fileName = fileName.substring(0, lastIndex);

        String[] split = fileName.split("-");
        String entity = split[0];

//        String[] label = labels.split(":");
//        Collections.reverse(Arrays.asList(label));
//        labels = String.join(":", label);

        String cypher = "LOAD CSV WITH HEADERS from '" + filePath + "' as line " +
                "create (n:" + labels + ":" + fileName + "{" + lineName + "}) ";
        if (fileName.contains("关联") || fileName.contains("关系")) {
            cypher = "LOAD CSV WITH HEADERS FROM '" + filePath + "' AS line  \n" +
                    "MATCH (from:" + entity + "{name:line.from}),(to:" + entity + "{name:line.to})  \n" +
                    "call apoc.merge.relationship(from, line.property, {}, {}, to) yield rel return *";
        }

        System.out.println(filePath);
        // 执行 LOAD CSV 语句
        neo4jUtil.excuteCypherSql(cypher);
    }

    public List query(String nodeLabel) {
        String cypher = "match (n:" + nodeLabel.trim() + ") return n.name as title ,id(n) as key;";
        List<HashMap<String, Object>> graphItem = neo4jUtil.getGraphItem(cypher);
        return graphItem;
    }

    public List getAllLabels() {
        List<List<Map<String, Object>>> node = new ArrayList<>();
        List<Map<String, Object>> nodTree = new ArrayList<>();
        try {
            String cypher = "match (n) return labels(n) as labels,last(labels(n)) as lastLabels";
            List<HashMap<String, Object>> nodeLabels = neo4jUtil.getGraphItem(cypher);
            for (int i = 0; i < nodeLabels.size(); i++) {//生成目录Titel,key
                List<Map<String, Object>> treeChildren = new ArrayList<>();
                JSONArray treeList;
                treeList = JSONArray.parseArray(nodeLabels.get(i).get("labels").toString());
                String key = i + "-";
                for (int j = 0; j < treeList.size(); j++) {
                    Map<String, Object> root = new HashMap<>();
                    key = key + j + "-";
                    root.put("title", treeList.get(j));
                    root.put("key", key.substring(0, key.length() - 1));
                    treeChildren.add(root);
                }
                node.add(treeChildren);
            }
            //装载目录层级e
            for (int i = 0; i < node.size(); i++) {
                for (int j = node.get(i).size(); j >= 0; j--) {
                    if (j < node.get(i).size() && j - 1 >= 0) {
                        List childrenList = new ArrayList<>();
                        childrenList.add(node.get(i).get(j));
                        node.get(i).get(j - 1).put("children", childrenList);
                    }
                }
                nodTree.add(node.get(i).get(0));
            }
            //合并目录递归实现
            nodTree = this.getMenu(nodTree);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return nodTree;
    }

    private List getMenu(List<Map<String, Object>> nodTree) {
        Map<String, Integer> map = new HashMap<>();
        List<Map<String, Object>> tree = new ArrayList();
        for (Map<String, Object> item : nodTree) {
            Map<String, Object> result = new HashMap<>();
            List chilrendNode = new ArrayList();
            if (map.containsKey(item.get("title").toString())) {
                for (Map<String, Object> node : tree) {
                    if (item.get("title").toString().equals(node.get("title").toString())) {
                        if (item.containsKey("children") && node.containsKey("children")) {
                            chilrendNode.addAll((List) node.get("children"));
                            chilrendNode.addAll((List) item.get("children"));
                            node.put("children", this.getMenu(chilrendNode));
                        }
                    }
                }
            } else {
                map.put(item.get("title").toString(), 1);
                result.put("title", item.get("title").toString());
                result.put("key", item.get("key").toString());
                if (item.containsKey("children") && item.get("children") != null) {
                    result.put("children", this.getMenu((List) item.get("children")));
                } else {
                    result.put("children", (List) item.get("children"));
                }

                tree.add(result);
            }
        }
        return tree;
    }

    public List getNodes(String nodeIds, String nodeName) {
        List<HashMap<String, Object>> graphItem;
        if (StringUtils.isNotBlank(nodeName)) {
            String cypher = "start n=node(*) where n.name contains  '" + nodeName + "' return last(labels(n)) as lastLabel,head(labels(n)) as headLabel,labels(n) as labels, id(n) as id, n.fileId as fileId,n.name as name,n.icons as icons,n.putTime as putTime";
            graphItem = neo4jUtil.getGraphItem(cypher);
        } else {
            JSONArray jsonArray = JSONArray.parseArray(nodeIds);
            Object collect = jsonArray.stream().map(String::valueOf).collect(Collectors.joining(","));
            String cypher = "start n=node(" + collect + ") match (n) return last(labels(n)) as lastLabel,head(labels(n)) as headLabel,labels(n) as labels, id(n) as id, n.fileId as fileId,n.name as name,n.icons as icons,n.putTime as putTime";
            graphItem = neo4jUtil.getGraphItem(cypher);
        }

        List<HashMap<Object, Object>> collect1 = graphItem.stream().map(nodeMap -> {

            HashMap<Object, Object> map = new HashMap<>();
            map.put("id", nodeMap.get("id"));
            map.put("fileId", nodeMap.get("fileId"));
            map.put("name", nodeMap.get("name"));
            map.put("show", true);
            map.put("type", "entity");
            map.put("labels", nodeMap.get("lastLabel"));
            map.put("treeNode", nodeMap.get("labels"));
            map.put("stroke", "#aaa");
            map.put("fill", !Objects.equals(nodeMap.get("putTime").toString(), "NULL")
                    && (TimeUtil.getDayStartTime(new Date(Long.parseLong(nodeMap.get("putTime").toString()))) > System.currentTimeMillis()
                    || TimeUtil.getDayEndTime(new Date(Long.parseLong(nodeMap.get("putTime").toString()))) < System.currentTimeMillis())
                    ? "rgba(255,255,255,0)" : "#9d53cf");
            map.put("radius", 20);
            if (Objects.nonNull(nodeMap.get("headLabel"))) {
                map.put("icon", graphImage.getGraphImage(nodeMap.get("headLabel").toString()));
            }
//            map.put("menu", this.getMenu(nodeMap.get("lastLabel").toString()).get("menu"));
            return map;
        }).collect(Collectors.toList());

        return collect1;
    }

    public Map getMenu(String label) {
        Map<String, Object> nodeMap = new HashMap<>();
        if ("一级系统".equals(label)) {//系统
            nodeMap.put("menu", JSONArray.parseArray(
                    "[{'name':'隐藏', 'icon': '\uf070','fill': '#202a33', 'count': '25'}, {'name':'对比', 'icon': '\uf0ec','fill': '#202a33', 'count': '25'},{ 'name':'扩展', 'icon':'\uf065', 'fill':'#202a33','count':'25', "
                            + "'secMenu':[{'name':'全部知识', 'icon': '\uf20e', 'fill': '#202a33', 'count':'25'},{'name':'设计知识', 'icon': '\uf044', 'fill': '#202a33', 'count':'25'},{ 'name': '二级系统', 'icon': '\uf17a', 'fill': '#202a33', 'count': '25' },{ 'name': '历史型号', 'icon': '\uf1da', 'fill': '#202a33', 'count': '25' },{ 'name': '历史对比', 'icon': '\uf0ec', 'fill': '#202a33', 'count': '25' }]}, "
                            + "{ 'name': '标记', 'icon': '\uf08d', 'fill': '#202a33', 'count': '25' }]"));
        } else if ("二级系统".equals(label)) {
            nodeMap.put("menu", JSONArray.parseArray(
                    "[{'name':'隐藏', 'icon': '\uf070','fill': '#202a33', 'count': '25'}, {'name':'对比', 'icon': '\uf0ec','fill': '#202a33', 'count': '25'},{ 'name':'扩展', 'icon':'\uf065', 'fill':'#202a33','count':'25', "
                            + "'secMenu':[{'name':'全部知识', 'icon': '\uf20e', 'fill': '#202a33', 'count':'25'},{'name':'设计知识', 'icon': '\uf044', 'fill': '#202a33', 'count':'25'},{ 'name': '三级系统', 'icon': '\uf17a', 'fill': '#202a33', 'count': '25' },{ 'name': '历史型号', 'icon': '\uf1da', 'fill': '#202a33', 'count': '25' },{ 'name': '历史对比', 'icon': '\uf0ec', 'fill': '#202a33', 'count': '25' }]}, "
                            + "{ 'name': '标记', 'icon': '\uf08d', 'fill': '#202a33', 'count': '25' }]"));
        } else if ("三级系统".equals(label)) {
            nodeMap.put("menu", JSONArray.parseArray(
                    "[{'name':'隐藏', 'icon': '\uf070','fill': '#202a33', 'count': '25'}, {'name':'对比', 'icon': '\uf0ec','fill': '#202a33', 'count': '25'},{ 'name':'扩展', 'icon':'\uf065', 'fill':'#202a33','count':'25', "
                            + "'secMenu':[{'name':'全部知识', 'icon': '\uf20e', 'fill': '#202a33', 'count':'25'},{'name':'设备', 'icon': '\uf0a0', 'fill': '#202a33', 'count':'25'},{ 'name': '材料', 'icon': '\uf1b3', 'fill': '#202a33', 'count': '25' },"
                            + "{'name':'重要阀门', 'icon': '\uf074', 'fill': '#202a33', 'count':'25'},{'name':'其它管路附件', 'icon': '\uf258', 'fill': '#202a33', 'count':'25'},"
                            + "{'name':'质量问题知识', 'icon': '\uf1ea', 'fill': '#202a33', 'count':'25'},{'name':'设计知识', 'icon': '\uf044', 'fill': '#202a33', 'count':'25'},"
                            + "{'name':'四级系统', 'icon': '\uf17a', 'fill': '#202a33', 'count':'25'},{ 'name': '历史型号', 'icon': '\uf1da', 'fill': '#202a33', 'count': '25' },{ 'name': '历史对比', 'icon': '\uf0ec', 'fill': '#202a33', 'count': '25' }]}, "
                            + "{ 'name': '标记', 'icon': '\uf08d', 'fill': '#202a33', 'count': '25' }]"));
        } else if ("四级系统".equals(label)) {
            nodeMap.put("menu", JSONArray.parseArray(
                    "[{'name':'隐藏', 'icon': '\uf070','fill': '#202a33', 'count': '25'}, {'name':'对比', 'icon': '\uf0ec','fill': '#202a33', 'count': '25'},{ 'name':'扩展', 'icon':'\uf065', 'fill':'#202a33','count':'25', "
                            + "'secMenu':[{'name':'全部知识', 'icon': '\uf20e', 'fill': '#202a33', 'count':'25'},{'name':'管路附件', 'icon': '\uf0c1', 'fill': '#202a33', 'count':'25'},{ 'name': '材料', 'icon': '\uf1b3', 'fill': '#202a33', 'count': '25' },{ 'name': '历史型号', 'icon': '\uf1da', 'fill': '#202a33', 'count': '25' },{ 'name': '历史对比', 'icon': '\uf0ec', 'fill': '#202a33', 'count': '25' }]}, "
                            + "{ 'name': '标记', 'icon': '\uf08d', 'fill': '#202a33', 'count': '25' }]"));
        } else if ("工作介质".equals(label)) {//材料
            nodeMap.put("menu", JSONArray.parseArray(
                    "[{'name':'隐藏', 'icon': '\uf070','fill': '#202a33', 'count': '25'}, {'name':'对比', 'icon': '\uf0ec','fill': '#202a33', 'count': '25'},{ 'name':'扩展', 'icon':'\uf065', 'fill':'#202a33','count':'25', "
                            + "'secMenu':[{'name':'全部知识', 'icon': '\uf20e', 'fill': '#202a33', 'count':'25'},{'name':'设计知识', 'icon': '\uf044', 'fill': '#202a33', 'count':'25'},{ 'name': '历史型号', 'icon': '\uf1da', 'fill': '#202a33', 'count': '25' },{ 'name': '历史对比', 'icon': '\uf0ec', 'fill': '#202a33', 'count': '25' }]}, "
                            + "{ 'name': '标记', 'icon': '\uf08d', 'fill': '#202a33', 'count': '25' }]"));
        } else if ("结构材料".equals(label)) {
            nodeMap.put("menu", JSONArray.parseArray(
                    "[{'name':'隐藏', 'icon': '\uf070','fill': '#202a33', 'count': '25'}, {'name':'对比', 'icon': '\uf0ec','fill': '#202a33', 'count': '25'},{ 'name':'扩展', 'icon':'\uf065', 'fill':'#202a33','count':'25', "
                            + "'secMenu':[{'name':'全部知识', 'icon': '\uf20e', 'fill': '#202a33', 'count':'25'},{'name':'设计知识', 'icon': '\uf044', 'fill': '#202a33', 'count':'25'},{ 'name': '历史型号', 'icon': '\uf1da', 'fill': '#202a33', 'count': '25' },{ 'name': '历史对比', 'icon': '\uf0ec', 'fill': '#202a33', 'count': '25' }]}, "
                            + "{ 'name': '标记', 'icon': '\uf08d', 'fill': '#202a33', 'count': '25' }]"));
        } else if ("其它材料".equals(label)) {
            nodeMap.put("menu", JSONArray.parseArray(
                    "[{'name':'隐藏', 'icon': '\uf070','fill': '#202a33', 'count': '25'}, {'name':'对比', 'icon': '\uf0ec','fill': '#202a33', 'count': '25'},{ 'name':'扩展', 'icon':'\uf065', 'fill':'#202a33','count':'25', "
                            + "'secMenu':[{'name':'全部知识', 'icon': '\uf20e', 'fill': '#202a33', 'count':'25'},{'name':'设计知识', 'icon': '\uf044', 'fill': '#202a33', 'count':'25'},{ 'name': '历史型号', 'icon': '\uf1da', 'fill': '#202a33', 'count': '25' },{ 'name': '历史对比', 'icon': '\uf0ec', 'fill': '#202a33', 'count': '25' }]}, "
                            + "{ 'name': '标记', 'icon': '\uf08d', 'fill': '#202a33', 'count': '25' }]"));
        } else if ("大型机组".equals(label)) {//设备
            nodeMap.put("menu", JSONArray.parseArray(
                    "[{'name':'隐藏', 'icon': '\uf070','fill': '#202a33', 'count': '25'}, {'name':'对比', 'icon': '\uf0ec','fill': '#202a33', 'count': '25'}, { 'name':'扩展', 'icon':'\uf065', 'fill':'#202a33','count':'25', "
                            + "'secMenu':[{'name':'全部知识', 'icon': '\uf20e', 'fill': '#202a33', 'count':'25'},{'name':'材料', 'icon': '\uf1b3', 'fill': '#202a33', 'count':'25'},{'name':'质量问题知识', 'icon': '\uf1ea', 'fill': '#202a33', 'count':'25'},"
                            + "{'name':'设计知识', 'icon': '\uf044', 'fill': '#202a33', 'count':'25'},{ 'name': '一般设备', 'icon': '\uf233', 'fill': '#202a33', 'count': '25' },{ 'name': '历史型号', 'icon': '\uf1da', 'fill': '#202a33', 'count': '25' },{ 'name': '历史对比', 'icon': '\uf0ec', 'fill': '#202a33', 'count': '25' }]}, "
                            + "{ 'name': '标记', 'icon': '\uf08d', 'fill': '#202a33', 'count': '25' }]"));
        } else if ("一般设备".equals(label)) {
            nodeMap.put("menu", JSONArray.parseArray(
                    "[{'name':'隐藏', 'icon': '\uf070','fill': '#202a33', 'count': '25'}, {'name':'对比', 'icon': '\uf0ec','fill': '#202a33', 'count': '25'}, { 'name':'扩展', 'icon':'\uf065', 'fill':'#202a33','count':'25', "
                            + "'secMenu':[{'name':'全部知识', 'icon': '\uf20e', 'fill': '#202a33', 'count':'25'},{'name':'材料', 'icon': '\uf1b3', 'fill': '#202a33', 'count':'25'},{'name':'质量问题知识', 'icon': '\uf1ea', 'fill': '#202a33', 'count':'25'},"
                            + "{'name':'设计知识', 'icon': '\uf044', 'fill': '#202a33', 'count':'25'},{ 'name': '设备部件', 'icon': '\uf12e', 'fill': '#202a33', 'count': '25' },{ 'name': '历史型号', 'icon': '\uf1da', 'fill': '#202a33', 'count': '25' },{ 'name': '历史对比', 'icon': '\uf0ec', 'fill': '#202a33', 'count': '25' }]}, "
                            + "{ 'name': '标记', 'icon': '\uf08d', 'fill': '#202a33', 'count': '25' }]"));
        } else if ("设备部件".equals(label)) {
            nodeMap.put("menu", JSONArray.parseArray(
                    "[{'name':'隐藏', 'icon': '\uf070','fill': '#202a33', 'count': '25'}, {'name':'对比', 'icon': '\uf0ec','fill': '#202a33', 'count': '25'}, "
                            + "{ 'name':'扩展', 'icon':'\uf065', 'fill':'#202a33','count':'25', "
                            + "'secMenu':[{'name':'全部知识', 'icon': '\uf20e', 'fill': '#202a33', 'count':'25'},{ 'name': '历史型号', 'icon': '\uf1da', 'fill': '#202a33', 'count': '25' },{ 'name': '历史对比', 'icon': '\uf0ec', 'fill': '#202a33', 'count': '25' }]}, "
                            + "{ 'name': '标记', 'icon': '\uf08d', 'fill': '#202a33', 'count': '25' }]"));
        } else if ("重要阀门".equals(label)) {//管路附件
            nodeMap.put("menu", JSONArray.parseArray(
                    "[{'name':'隐藏', 'icon': '\uf070','fill': '#202a33', 'count': '25'}, {'name':'对比', 'icon': '\uf0ec','fill': '#202a33', 'count': '25'}, { 'name':'扩展', 'icon':'\uf065', 'fill':'#202a33','count':'25', "
                            + "'secMenu':[{'name':'全部知识', 'icon': '\uf20e', 'fill': '#202a33', 'count':'25'},{'name':'材料', 'icon': '\uf1b3', 'fill': '#202a33', 'count':'25'},{'name':'设备部件', 'icon': '\uf12e', 'fill': '#202a33', 'count':'25'},"
                            + "{ 'name': '质量问题知识', 'icon': '\uf1ea', 'fill': '#202a33', 'count': '25' }, { 'name':'设计知识', 'icon': '\uf044', 'fill': '#202a33', 'count': '25' },{ 'name': '历史型号', 'icon': '\uf1da', 'fill': '#202a33', 'count': '25' },{ 'name': '历史对比', 'icon': '\uf0ec', 'fill': '#202a33', 'count': '25' }]}, "
                            + "{ 'name': '标记', 'icon': '\uf08d', 'fill': '#202a33', 'count': '25' }]"));
        } else if ("隔振元件".equals(label)) {
            nodeMap.put("menu", JSONArray.parseArray(
                    "[{'name':'隐藏', 'icon': '\uf070','fill': '#202a33', 'count': '25'}, {'name':'对比', 'icon': '\uf0ec','fill': '#202a33', 'count': '25'}, { 'name':'扩展', 'icon':'\uf065', 'fill':'#202a33','count':'25', "
                            + "'secMenu':[{'name':'全部知识', 'icon': '\uf20e', 'fill': '#202a33', 'count':'25'},{'name':'材料', 'icon': '\uf1b3', 'fill': '#202a33', 'count':'25'},{'name':'设计知识', 'icon': '\uf044', 'fill': '#202a33', 'count':'25'},{ 'name': '历史型号', 'icon': '\uf1da', 'fill': '#202a33', 'count': '25' },{ 'name': '历史对比', 'icon': '\uf0ec', 'fill': '#202a33', 'count': '25' }]}, "
                            + "{ 'name': '标记', 'icon': '\uf08d', 'fill': '#202a33', 'count': '25' }]"));
        } else if ("其它管路附件".equals(label)) {
            nodeMap.put("menu", JSONArray.parseArray(
                    "[{'name':'隐藏', 'icon': '\uf070','fill': '#202a33', 'count': '25'}, {'name':'对比', 'icon': '\uf0ec','fill': '#202a33', 'count': '25'}, { 'name':'扩展', 'icon':'\uf065', 'fill':'#202a33','count':'25', "
                            + "'secMenu':[{'name':'全部知识', 'icon': '\uf20e', 'fill': '#202a33', 'count':'25'},{'name':'材料', 'icon': '\uf1b3', 'fill': '#202a33', 'count':'25'},{'name':'设计知识', 'icon': '\uf044', 'fill': '#202a33', 'count':'25'},{ 'name': '历史型号', 'icon': '\uf1da', 'fill': '#202a33', 'count': '25' },{ 'name': '历史对比', 'icon': '\uf0ec', 'fill': '#202a33', 'count': '25' }]}, "
                            + "{ 'name': '标记', 'icon': '\uf08d', 'fill': '#202a33', 'count': '25' }]"));
        } else if ("设施".equals(label)) {//装备
            nodeMap.put("menu", JSONArray.parseArray(
                    "[{'name':'隐藏', 'icon': '\uf070','fill': '#202a33', 'count': '25'}, {'name':'对比', 'icon': '\uf0ec','fill': '#202a33', 'count': '25'}, { 'name':'扩展', 'icon':'\uf065', 'fill':'#202a33','count':'25', "
                            + "'secMenu':[{'name':'全部知识', 'icon': '\uf20e', 'fill': '#202a33', 'count':'25'},{'name':'型号', 'icon': '\uf113', 'fill': '#202a33', 'count':'25'},{ 'name': '历史型号', 'icon': '\uf1da', 'fill': '#202a33', 'count': '25' },{ 'name': '历史对比', 'icon': '\uf0ec', 'fill': '#202a33', 'count': '25' }]}, "
                            + "{ 'name': '标记', 'icon': '\uf08d', 'fill': '#202a33', 'count': '25' }]"));
        } else if ("型号".equals(label)) {
            nodeMap.put("menu", JSONArray.parseArray(
                    "[{'name':'隐藏', 'icon': '\uf070','fill': '#202a33', 'count': '25'}, {'name':'对比', 'icon': '\uf0ec','fill': '#202a33', 'count': '25'}, { 'name':'扩展', 'icon':'\uf065', 'fill':'#202a33','count':'25', "
                            + "'secMenu':[{'name':'全部知识', 'icon': '\uf20e', 'fill': '#202a33', 'count':'25'},{'name':'一级系统', 'icon': '\uf17a', 'fill': '#202a33', 'count':'25'},{'name':'设计知识', 'icon': '\uf044', 'fill': '#202a33', 'count':'25'},"
                            + "{ 'name':'质量问题知识', 'icon': '\uf1ea', 'fill': '#202a33', 'count':'25'},{ 'name': '历史型号', 'icon': '\uf1da', 'fill': '#202a33', 'count': '25' },{ 'name': '历史对比', 'icon': '\uf0ec', 'fill': '#202a33', 'count': '25' }]}, "
                            + "{ 'name': '标记', 'icon': '\uf08d', 'fill': '#202a33', 'count': '25' }]"));
        } else if ("方案设计".equals(label)) {
            nodeMap.put("menu", JSONArray.parseArray(
                    "[{'name':'隐藏', 'icon': '\uf070','fill': '#202a33', 'count': '25'}, {'name':'对比', 'icon': '\uf0ec','fill': '#202a33', 'count': '25'}, { 'name':'扩展', 'icon':'\uf065', 'fill':'#202a33','count':'25', "
                            + "'secMenu':[{'name':'全部知识', 'icon': '\uf20e', 'fill': '#202a33', 'count':'25'},{'name':'原则依据', 'icon': '\uf0f6', 'fill': '#202a33', 'count':'25'},{'name':'多方案论证', 'icon': '\uf24e', 'fill': '#202a33', 'count':'25'},"
                            + "{ 'name':'计算分析', 'icon': '\uf1de', 'fill': '#202a33', 'count':'25'},{ 'name':'运行模式', 'icon': '\uf1cb', 'fill': '#202a33', 'count':'25'},"
                            + "{ 'name':'外部接口', 'icon': '\uf1e6', 'fill': '#202a33', 'count':'25'},{ 'name':'六性措施', 'icon': '\uf20e', 'fill': '#202a33', 'count':'25'},"
                            + "{ 'name':'关键技术', 'icon': '\uf1c9', 'fill': '#202a33', 'count':'25'},{ 'name':'风险分析', 'icon': '\uf0e7', 'fill': '#202a33', 'count':'25'},{ 'name': '历史型号', 'icon': '\uf1da', 'fill': '#202a33', 'count': '25' },{ 'name': '历史对比', 'icon': '\uf0ec', 'fill': '#202a33', 'count': '25' }]},"
                            + "{ 'name': '标记', 'icon': '\uf08d', 'fill': '#202a33', 'count': '25' }]"));
        } else if ("方案论证".equals(label)) {
            nodeMap.put("menu", JSONArray.parseArray(
                    "[{'name':'隐藏', 'icon': '\uf070','fill': '#202a33', 'count': '25'}, {'name':'对比', 'icon': '\uf0ec','fill': '#202a33', 'count': '25'}, { 'name':'扩展', 'icon':'\uf065', 'fill':'#202a33','count':'25', "
                            + "'secMenu':[{'name':'全部知识', 'icon': '\uf20e', 'fill': '#202a33', 'count':'25'},{'name':'原则依据', 'icon': '\uf0f6', 'fill': '#202a33', 'count':'25'},{'name':'架构方案', 'icon': '\uf0ea', 'fill': '#202a33', 'count':'25'},"
                            + "{ 'name':'参数论证', 'icon': '\uf24e', 'fill': '#202a33', 'count':'25'},{ 'name':'配置方案', 'icon': '\uf085', 'fill': '#202a33', 'count':'25'},"
                            + "{ 'name':'运行模式', 'icon': '\uf1cb', 'fill': '#202a33', 'count':'25'},{ 'name':'关键技术', 'icon': '\uf1c9', 'fill': '#202a33', 'count':'25'},"
                            + "{ 'name':'风险分析', 'icon': '\uf0e7', 'fill': '#202a33', 'count':'25'},{ 'name': '历史型号', 'icon': '\uf1da', 'fill': '#202a33', 'count': '25' },{ 'name': '历史对比', 'icon': '\uf0ec', 'fill': '#202a33', 'count': '25' }]},"
                            + "{ 'name': '标记', 'icon': '\uf08d', 'fill': '#202a33', 'count': '25' }]"));
        } else {
            nodeMap.put("menu", JSONArray.parseArray(
                    "[{'name':'隐藏', 'icon': '\uf070','fill': '#202a33', 'count': '25'}, {'name':'对比', 'icon': '\uf0ec','fill': '#202a33', 'count': '25'}, "
                            + "{ 'name':'扩展', 'icon':'\uf065', 'fill':'#202a33','count':'25', "
                            + "'secMenu':[{'name':'全部知识', 'icon': '\uf20e', 'fill': '#202a33', 'count':'25'},{ 'name': '历史型号', 'icon': '\uf1da', 'fill': '#202a33', 'count': '25' },{ 'name': '历史对比', 'icon': '\uf0ec', 'fill': '#202a33', 'count': '25' }]}, "
                            + "{ 'name': '标记', 'icon': '\uf08d', 'fill': '#202a33', 'count': '25' }]"));
        }
        return nodeMap;
    }

    public Map<String, Object> getNodes(String relationShip) {
        String cypher2 = "MATCH p=()-[r:" + relationShip + "]->(n) return p";
        HashMap<String, Object> graphNodeAndShip = neo4jUtil.getGraphNodeAndShip(cypher2);
        List<HashMap<String, Object>> graphItem = (List<HashMap<String, Object>>) graphNodeAndShip.get("node");
        if (Objects.isNull(graphItem)) {
            return new HashMap<>();
        }

        List<HashMap<Object, Object>> collect1 = graphItem.stream().map(nodeMap -> {

            HashMap<Object, Object> map = new HashMap<>();
            map.put("id", nodeMap.get("id"));
            map.put("fileId", nodeMap.get("fileId"));
            map.put("name", nodeMap.get("name"));
            map.put("show", true);
            map.put("type", "entity");
            map.put("labels", nodeMap.get("lastLabel"));
            map.put("treeNode", nodeMap.get("labels"));
            map.put("stroke", "#aaa");
            map.put("fill", Objects.nonNull(nodeMap.get("putTime"))
                    && !Objects.equals(nodeMap.get("putTime").toString(), "NULL")
                    && (TimeUtil.getDayStartTime(new Date(Long.parseLong(nodeMap.get("putTime").toString()))) > System.currentTimeMillis()
                    || TimeUtil.getDayEndTime(new Date(Long.parseLong(nodeMap.get("putTime").toString()))) < System.currentTimeMillis())
                    ? "rgba(255,255,255,0)" : "#9d53cf");
            map.put("radius", 20);
            if (Objects.nonNull(nodeMap.get("headLabel"))) {
                map.put("icon", graphImage.getGraphImage(nodeMap.get("headLabel").toString()));
            }
//            map.put("menu", this.getMenu(nodeMap.get("lastLabel").toString()).get("menu"));
            return map;
        }).collect(Collectors.toList());

        Map<String, Object> map = new HashMap<>(2);
        map.put("nodes", collect1);
        map.put("links", graphNodeAndShip.get("relationship"));
        return map;
    }

    public Result uploadExcelToNeo4jData2(MultipartFile file) throws IOException {
        //文件处理
        List<Map> examInfoList = new ArrayList<>();

        EasyExcel.read(file.getInputStream(), ExamMsg.class, new ExamListener(examInfoList)).sheet().doRead();
        Map<String, Object> entityNode = new HashMap<>();
        entityNode.put("props", examInfoList);

        String cypher = "UNWIND $props AS properties CREATE (n:Person) SET n = properties RETURN n";

        neo4jUtil.excuteCypherSql(cypher, entityNode);
        return Result.success();
    }

    public static class ExamListener extends AnalysisEventListener<ExamMsg> {

        // 自定义消费者函数接口用于自定义监听器中数据组装
        public List<Map> examInfoList;

        public ExamListener(List<Map> examInfoList) {
            this.examInfoList = examInfoList;
        }
        // 每行读取完成之后会执行
        @Override
        public void invoke(ExamMsg data, AnalysisContext context) {

            // 按照格式组装数据
            if (data.getName() != null) {
                Map map = JSONObject.parseObject(JSONObject.toJSONString(data), Map.class);
                examInfoList.add(map);
            } else {
                // 倒序添加选择题信息,只对最后一个进行添加选项数据信息
//                Map<String, Object> examInfo = examInfoList.get(examInfoList.size() - 1);
//                examInfo.put("explain", examInfo.get("explain") + data.getExplain());
            }
        }

        // 每行读取完成之后执行
        @Override
        public void doAfterAllAnalysed(AnalysisContext context) {

        }
    }
}
